﻿using Senparc.Weixin.Work.AdvancedAPIs;
using Senparc.Weixin.Work.Containers;
using Senparc.Weixin.Work.Entities;
using Senparc.Weixin.Work.MessageContexts;
using Senparc.Weixin.Work.MessageHandlers;
using Single.Logger;
using System.Collections.Concurrent;
using System.Xml.Linq;

namespace Single.WebApp.Components.Weixin
{
    public class CustomWorkMessageHandler : WorkMessageHandler<DefaultWorkMessageContext>
    {
        private string _agentId, _secret;

        /// <summary>
        /// 加密参数集合
        /// </summary>
        private PostModel _postModel;

        /// <summary>
        /// 接口凭据
        /// </summary>
        public string AccessToken
        {
            get { return AccessTokenContainer.TryGetToken(_postModel.CorpId, _secret); }
        }

        /// <summary>
        /// 请求列队
        /// </summary>
        private static ConcurrentDictionary<string, DateTime> HandlerQueue = new ConcurrentDictionary<string, DateTime>();

        /// <summary>
        /// 公用列队委托
        /// </summary>
        public IWorkResponseMessageBase HandlerQueueFunc(IWorkRequestMessageBase requestMessage, Func<IWorkResponseMessageBase> func)
        {
            DateTime value = DateTime.Now;

            if (HandlerQueue.TryAdd(requestMessage.FromUserName, value))
            {
                try { return func.Invoke(); }
                catch { }
                finally { HandlerQueue.TryRemove(requestMessage.FromUserName, out value); }
            }
            else
            {
                if (HandlerQueue.TryGetValue(requestMessage.FromUserName, out value))
                {
                    if (value.AddSeconds(10) < DateTime.Now)
                    {
                        HandlerQueue.TryRemove(requestMessage.FromUserName, out value);
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public CustomWorkMessageHandler(string agentId, string secret, Stream inputStream, PostModel postModel, int maxRecordCount = 0, IServiceProvider serviceProvider = null) : base(inputStream, postModel, maxRecordCount, serviceProvider)
        {
            this._agentId = agentId;
            this._secret = secret;
            this._postModel = postModel;

            OmitRepeatedMessage = true;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public CustomWorkMessageHandler(string agentId, string secret, XDocument requestDocument, PostModel postModel, int maxRecordCount = 0, IServiceProvider serviceProvider = null) : base(requestDocument, postModel, maxRecordCount, serviceProvider)
        {
            this._agentId = agentId;
            this._secret = secret;
            this._postModel = postModel;

            OmitRepeatedMessage = true;
        }

        /// <summary>
        /// 执行并输出响应
        /// </summary>
        public async Task<string> ExecuteOutContent()
        {
            try
            {
                await ExecuteAsync(default(CancellationToken));
            }
            catch (Exception ex)
            {
                LoggerHelper.Error(ex.Message, ex);
            }

            if (FinalResponseDocument != null)
            {
                return FinalResponseDocument.ToString();
            }

            return null;
        }

        /// <summary>
        /// 默认回复
        /// </summary>
        public override IWorkResponseMessageBase DefaultResponseMessage(IWorkRequestMessageBase requestMessage)
        {
            return null;
        }

        /// <summary>
        /// 发送文本消息
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="value"></param>
        public void SendMessage(string userid, string value)
        {
            MassApi.SendText(AccessToken, AgentId.Value.ToString(), value, userid);
        }

        /// <summary>
        /// 自动回复
        /// </summary>
        public IWorkResponseMessageBase AutoReplyText(string content)
        {
            var responseMessage = CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = content;
            return responseMessage;
        }

        /// <summary>
        /// BuildResponseMessageAsync
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override Task BuildResponseMessageAsync(CancellationToken cancellationToken)
        {
            return base.BuildResponseMessageAsync(cancellationToken);
        }
    }
}